#ifndef __FLASH_H_
#define __FLASH_H_

/* =========================== 用户配置 =========================== */

#include "stdint.h"
#include "main.h"

/* Flash 页大小（F103 是 1KB） */
#ifndef FLASH_PAGE_SIZE
#define FLASH_PAGE_SIZE 1024 * 2
#endif

/* Flash 起始地址与结束地址（根据芯片调整） */
#define FLASH_BASE_ADDR 0x0801F000
#define FLASH_END_ADDR 0x0801FFFF

/* 是否启用写入前自动擦除（整页） */
#define FLASH_AUTO_ERASE_BEFORE_WRITE 1

static inline void FLASH_INIT_FUN(void) /* 用户flash初始化接口 */
{

}

static inline void FLASH_UNLOCK(void) /* 用户flash解锁接口 */
{
    HAL_FLASH_Unlock();
}

static inline void FLASH_LOCK(void) /* 用户flash上锁接口 */
{
    HAL_FLASH_Lock();
}

static inline uint8_t FLASH_ERASE_PAGE(uint32_t page_address) /* 用户flash擦除接口 */
{
    uint32_t page_error = 0;
    FLASH_EraseInitTypeDef erase_init = {
        .TypeErase = FLASH_TYPEERASE_PAGES,
        .PageAddress = page_address,
        .NbPages = 1};

    if (HAL_FLASHEx_Erase(&erase_init, &page_error) != HAL_OK)
        return 1;
    return 0;
}

static inline uint8_t FLASH_WRITE_WORD(uint32_t address, uint32_t data) /* 用户flash写入接口 */
{
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data) != HAL_OK)
        return 1;
    return 0;
}

/* =========================== 外部声明 =========================== */

#include "stdint.h"

/**
 * @brief  初始化 Flash 模块（检查是否可写）
 */
void flash_init(void);

/**
 * @brief  写入数据到 Flash（带擦除）
 * @param  addr: 起始地址（必须是页对齐）
 * @param  buf: 数据缓冲区
 * @param  size: 数据大小（字节）
 * @retval 0: 成功，1: 失败
 */
uint8_t flash_write(uint32_t addr, const uint32_t *buf, uint32_t size);

/**
 * @brief  从 Flash 读取数据
 * @param  addr: 起始地址
 * @param  buf: 数据缓冲区
 * @param  size: 数据大小（字节）
 */
void flash_read(uint32_t addr, uint32_t *buf, uint32_t size);

/**
 * @brief  擦除指定页
 * @param  addr: 页起始地址
 * @retval 0: 成功，1: 失败
 */
uint8_t flash_erase_page(uint32_t addr);

#endif
